home *** CD-ROM | disk | FTP | other *** search
-
- /* file FPScroll.c
- Routines for using the standard scroll bars with floating
- point numbers providing scrolling accross the range of
- float, double, or whatever...
- Copyright (c) 1997 by John Montbriand. All Rights Reserved.
- Permission granted for public use.
- Distribute freely in areas where the laws of copyright apply.
- USE AT YOUR OWN RISK.
- DO NOT DISTRIBUTE MODIFIED COPIES.
- Comments/questions/postcards to the author at the address:
- John Montbriand
- P.O. Box. 1133
- Saskatoon Saskatchewan Canada
- S7K 3N2
- or by email at:
- tinyjohn@sk.sympatico.ca
- If you would like to have:
- technical support regarding this file, send a postcard.
- see also:
- http://www3.sk.sympatico.ca/tinyjohn
- */
-
-
- #include "FPScroll.h"
- #include <fp.h>
- #include <OSUtils.h>
- #include <Memory.h>
- #include <MixedMode.h>
-
- typedef struct {
- float min, max, value, prevthumb;
- FPScrollActionProc actionproc;
- long reference;
- } FPScrollVars;
-
- #pragma segment fpscroll
-
- ControlHandle NewFPScrollBar(WindowPtr wp, Rect* box, FPScrollActionProc action) {
- ControlHandle control;
- FPScrollVars dv;
- Handle varshandle;
-
- /* set up dv structure */
- dv.min = dv.max = dv.value = 0;
- dv.actionproc = action;
- dv.reference = 0;
- if (PtrToHand(&dv, &varshandle, sizeof(dv)) != noErr) return NULL;
-
- /* create the control */
- control = NewControl(wp, box, "\p", true, 0, 0, kFPScrollPositions, scrollBarProc, (long) varshandle);
-
- /* return the result */
- if (control == NULL) {
- DisposeHandle(varshandle);
- return NULL;
- } else {
- HiliteControl(control, 255);
- return control;
- }
- }
-
- void DisposeFPScrollBar(ControlHandle control) {
- FPScrollVars **dv;
- dv = (FPScrollVars **) GetCRefCon(control);
- DisposeHandle((Handle) dv);
- DisposeControl(control);
- }
-
- /* maps a float value from the domain [dmin,dmax] to the range [rmin,rmax] */
- static float FPMapValue(float value, float dmin, float dmax, float rmin, float rmax) {
- float slope, b;
- slope = (rmax-rmin) / (dmax-dmin);
- b = rmin - slope * dmin;
- return (slope * value) + b;
- }
-
- float GetFPCtlMin(ControlHandle control) {
- FPScrollVars **dv;
- dv = (FPScrollVars **) GetCRefCon(control);
- return (**dv).min;
- }
-
- float GetFPCtlMax(ControlHandle control) {
- FPScrollVars **dv;
- dv = (FPScrollVars **) GetCRefCon(control);
- return (**dv).max;
- }
-
- float GetFPCtlValue(ControlHandle control) {
- FPScrollVars **dv;
- dv = (FPScrollVars **) GetCRefCon(control);
- return (**dv).value;
- }
-
- float GetFPThumbValue(ControlHandle control) {
- FPScrollVars **dv;
- dv = (FPScrollVars **) GetCRefCon(control);
- return (**dv).prevthumb;
- }
-
- long GetFPCtlReference(ControlHandle control) {
- FPScrollVars **dv;
- dv = (FPScrollVars **) GetCRefCon(control);
- return (**dv).reference;
- }
-
- void SetFPCtlReference(ControlHandle control, long ref) {
- FPScrollVars **dv;
- dv = (FPScrollVars **) GetCRefCon(control);
- (**dv).reference = ref;
- }
-
- void SetFPCtlMinMax(ControlHandle control, float min, float max) {
- float oldvalue, nextvalue;
- short newvalue;
- FPScrollVars **dv;
- dv = (FPScrollVars **) GetCRefCon(control);
-
- /* ensure the current value is in the new range */
- oldvalue = (**dv).value;
- if (oldvalue < min)
- nextvalue = min;
- else if (oldvalue > max)
- nextvalue = max;
- else nextvalue = oldvalue;
- (**dv).value = nextvalue;
-
- /* set the minimum and maximum */
- (**dv).min = min;
- (**dv).max = max;
-
- /* display the new settings */
- newvalue = roundtol(FPMapValue(nextvalue, min, max, 0, kFPScrollPositions));
- SetCtlValue(control, newvalue);
- HiliteControl(control, ((min == max) ? 255: 0));
- }
-
- void SetFPCtlValue(ControlHandle control, float value) {
- FPScrollVars **dv;
- float nextvalue;
- short newvalue;
- dv = (FPScrollVars **) GetCRefCon(control);
-
- /* ensure the value is in the control's range */
- if (value < (**dv).min)
- nextvalue = (**dv).min;
- else if (value > (**dv).max)
- nextvalue = (**dv).max;
- else nextvalue = value;
- (**dv).value = nextvalue;
-
- /* display the new settings */
- newvalue = roundtol(FPMapValue(nextvalue, (**dv).min, (**dv).max, 0, kFPScrollPositions));
- SetCtlValue(control, newvalue);
- }
-
- static pascal void FPScrollActionProcedure(ControlRef theControl, ControlPartCode partCode) {
- FPScrollVars **dv;
- dv = (FPScrollVars **) GetCRefCon(theControl);
- ((**dv).actionproc)(theControl, partCode, (**dv).reference);
- }
-
- void TrackFPControl(WindowPtr theWindow, ControlHandle control, Point where) {
- short partcode;
- ControlHandle theControl;
- partcode = FindControl(where, theWindow, &theControl);
- if (partcode != 0 && theControl == control) {
- FPScrollVars **dv;
- short newvalue;
- float nextvalue;
- dv = (FPScrollVars **) GetCRefCon(control);
- if (partcode == inThumb) {
- if (TrackControl(control, where, NULL) == inThumb) {
- newvalue = GetCtlValue(control);
- nextvalue = FPMapValue((float) newvalue, 0, kFPScrollPositions, (**dv).min, (**dv).max);
- if ((**dv).value != nextvalue) {
- (**dv).prevthumb = (**dv).value;
- (**dv).value = nextvalue;
- ((**dv).actionproc)(control, inThumb, (**dv).reference);
- }
- }
- } else {
- ControlActionUPP local_action;
- local_action = NewControlActionProc(FPScrollActionProcedure);
- TrackControl(control, where, local_action);
- DisposeRoutineDescriptor((UniversalProcPtr) local_action);
- }
- }
- }
-